#include "CSoulMgr.h"
#include "pb_cfg_soul.pb.h"
#include "CSoulConfig.h"
#include <iostream>
#include <fstream>
#include <vector>
#include "../mainctrl.h"
#include "MsgSoul.pb.h"

int CSoulMgr::LoadConfig(const char* szCfgPath)
{
    int iRet = 0;

    if (szCfgPath == NULL)
    {
        CT_ERROR(("Card Cfg Path is null"));
        return RET_SYSTEM_FAIL;
    }

    pb_cfg_soul stSoulPBConfig;
    std::fstream stFileInput(szCfgPath, std::ios::in | std::ios::binary);
    if (!stSoulPBConfig.ParseFromIstream(&stFileInput))
    {
        CT_ERROR(("Failed to Parse SoulCfg! %s", szCfgPath));
        return RET_SYSTEM_FAIL;
    }

    //解析配置文件内容
    //封印球配置
    for (int i = 0; i < stSoulPBConfig.ball_config_rows_size(); ++i)
    {
        const pb_cfg_soul_pb_cfg_ball_config_unit& stSoulPBConfigUnit
            = stSoulPBConfig.ball_config_rows(i);

        CSoulBallConfigData stConfigData;

        CPlayerAttr stPlayerAttr;
        unsigned char ucBallLevel;
        unsigned char ucAttrType;
        int iAttrValue;
        bool bIsBaseAttr;

        stConfigData._ucBallID = (unsigned char)stSoulPBConfigUnit.ball_id();

        ucBallLevel = 1;
        ucAttrType = (unsigned char)stSoulPBConfigUnit.attr_type1();
        iAttrValue = stSoulPBConfigUnit.attr_value1();
        stPlayerAttr.Clear();
        iRet = stPlayerAttr.SetAttr(ucAttrType, iAttrValue);
        CHECK_RETURN(iRet);
        iRet = stConfigData.AddBallAttr(ucBallLevel, stPlayerAttr);
        CHECK_RETURN(iRet);

        ucBallLevel = 2;
        bIsBaseAttr = stSoulPBConfigUnit.attr_type2() != 0;
        ucAttrType = (unsigned char)stSoulPBConfigUnit.attr_type2();
        iAttrValue = stSoulPBConfigUnit.attr_value2();
        stPlayerAttr.Clear();
        iRet = stPlayerAttr.SetAttr(ucAttrType, iAttrValue);
        CHECK_RETURN(iRet);
        iRet = stConfigData.AddBallAttr(ucBallLevel, stPlayerAttr);
        CHECK_RETURN(iRet);

        ucBallLevel = 3;
        bIsBaseAttr = stSoulPBConfigUnit.attr_type3() != 0;
        ucAttrType = (unsigned char)stSoulPBConfigUnit.attr_type3();
        iAttrValue = stSoulPBConfigUnit.attr_value3();
        stPlayerAttr.Clear();
        iRet = stPlayerAttr.SetAttr(ucAttrType, iAttrValue);
        CHECK_RETURN(iRet);
        iRet = stConfigData.AddBallAttr(ucBallLevel, stPlayerAttr);
        CHECK_RETURN(iRet);

        iRet = _stSoulBallConfig.AddConfig(stConfigData);
        CHECK_RETURN(iRet);
    }

    //"等"配置
    for (int i = 0; i < stSoulPBConfig.stat_config_rows_size(); ++i)
    {
        const pb_cfg_soul_pb_cfg_stat_config_unit& stSoulPBConfigUnit
            = stSoulPBConfig.stat_config_rows(i);

        CSoulStatConfigData stConfigData;
        
        stConfigData._ucStatID = (unsigned char)stSoulPBConfigUnit.stat_id();
        stConfigData._usNeedLevel = (unsigned short)stSoulPBConfigUnit.need_level();
        stConfigData._usNeedHunli = (unsigned short)stSoulPBConfigUnit.need_hunli();
        stConfigData._usSkillID1 = (unsigned int)stSoulPBConfigUnit.job1_skill_id();
        stConfigData._usSkillID2 = (unsigned int)stSoulPBConfigUnit.job2_skill_id();
        stConfigData._usSkillID3 = (unsigned int)stSoulPBConfigUnit.job3_skill_id();

        //包含的封印球ID
        if (strlen(stSoulPBConfigUnit.balls().c_str()) > 0)
        {
            std::string sBallIDs = stSoulPBConfigUnit.balls();
            const std::string sDel = ",";
            std::vector<std::string> vBallIDs;

            CTStringUtils::Split(sBallIDs, sDel, vBallIDs);
            for (unsigned int i = 0; i < vBallIDs.size(); ++i)
            {
                stConfigData._astBallIDs.AddOneItem((unsigned char)atoi(vBallIDs[i].c_str()));
            }
        }
        
        iRet = _stSoulStatConfig.AddConfig(stConfigData, _stSoulBallConfig);
        CHECK_RETURN(iRet);
    }

    return 0;
}

int CSoulMgr::LevelUp(CPlayerSoulData& stSoulData, int& iHunli, unsigned short usRoleLevel, unsigned char ucBallID, bool& bStatUp, MsgBallInfo& stMsgBallInfo)
{
    int iRet = 0;

    bStatUp = false;

    if (stSoulData._ucNowStat >= _stSoulStatConfig._ucMaxStatID)
    {
        return ERROR_SOUL_STAT_MAX_LEVEL;
    }

    if (stSoulData.IsMaxLevel(ucBallID))
    {
        return ERROR_SOUL_BALL_MAX_LEVEL;
    }

    CSoulStatConfigData stStatConfigData;
    iRet = _stSoulStatConfig.GetConfig(stSoulData._ucNowStat, stStatConfigData);
    CHECK_RETURN(iRet);

    //检查是否可以解开封印
    if (usRoleLevel < stStatConfigData._usNeedLevel)    //等级不足
    {
        return ERROR_SOUL_LEVEL_NOT_ENOUGH;
    }

    if (iHunli < (int)stStatConfigData._usNeedHunli)
    {
        return ERROR_SOUL_HUNLI_NOT_ENOUGH;
    }

    //扣除魂力
    iHunli -= stStatConfigData._usNeedHunli;

    //解封
    iRet = stSoulData.LevelUp(ucBallID);
    CHECK_RETURN(iRet);

    //获取属性
    CPlayerAttr stAddAttr;
    GetBallLevel(stSoulData, ucBallID, stAddAttr);

    stMsgBallInfo.set_ball_id(ucBallID);

    unsigned char ucBallLevel;
    iRet = stSoulData.GetBallLevel(ucBallID, ucBallLevel);
    CHECK_RETURN(iRet);
    stMsgBallInfo.set_ball_level(ucBallLevel);

    CPlayerAttr::T_ATTR_DATAS stPlayerAttrData;
    stAddAttr.GetAttr(stPlayerAttrData);
    for (int i = 0; i < stPlayerAttrData.Size(); ++i)
    {
        MsgTypeValuePair* pstMsgTypeValuePair = stMsgBallInfo.add_attr();
        pstMsgTypeValuePair->set_type(stPlayerAttrData[i]._ucType);
        pstMsgTypeValuePair->set_value(stPlayerAttrData[i]._iValue);
    }
    
    //检查全部封印球是否打开
    for (int i = 0; i < stStatConfigData._astBallIDs.Size(); ++i)
    {
        unsigned char ucBallID = stStatConfigData._astBallIDs[i];
        if (!stSoulData.IsMaxLevel(ucBallID))
        {
            return 0;
        }
    }

    bStatUp = true;
    //所有封印球都解封了
    iRet = stSoulData.StatUp();
    CHECK_RETURN(iRet);

    if (bStatUp)
    {
        CSoulStatConfigData stNowStatConfigData;
        if (RET_OK == _stSoulStatConfig.GetConfig(stSoulData._ucNowStat - 1, stNowStatConfigData))
        {
            int iIndex = CMainCtrl::m_pstMain->m_stPlayerSnsCommInfoHash.HashFind(stSoulData._uiGID);
            if (iIndex < 0)
            {
                CT_WARNING((""));
                return 0;
            }
            CPlayerSnsCommInfo& stPlayerSnsCommInfo = CMainCtrl::m_pstMain->m_stPlayerSnsCommInfoHash[iIndex];

            //发送跑马灯
            MsgTips stTips;
            stTips.set_type(1005);
            stTips.add_tip_argument(stPlayerSnsCommInfo._sRoleName());
            stTips.add_tip_argument(CTStringUtils::IntToString(stSoulData._ucNowStat));
            stTips.add_tip_argument(CTStringUtils::IntToString(stNowStatConfigData.GetSkillIDByCareer(stPlayerSnsCommInfo._ucCareer)));
            CMainCtrl::m_pstMain->SendOnlineTips(stTips);
        }
    }

    return 0;
}

bool CSoulMgr::CanUseSkill(CPlayerSoulData& stSoulData, unsigned char ucCareer, unsigned int uiSkillID)
{
    int iRet = 0;
    unsigned char ucNowStatID = stSoulData._ucNowStat;
    for (unsigned char i = 0; i < ucNowStatID; ++i)
    {
        CSoulStatConfigData stStatConfigData;
        iRet = _stSoulStatConfig.GetConfig(i, stStatConfigData);
        if (iRet != 0)
        {
            return false;
        }

        if (stStatConfigData.GetSkillIDByCareer(ucCareer) == uiSkillID)
        {
            return true;
        }
    }

    return false;
}

int CSoulMgr::GetSoulSkillList(CPlayerBaseInfo& stPlayerBaseInfo, CPlayerDetailInfo& stPlayerDetailInfo, ::google::protobuf::RepeatedField< ::google::protobuf::int32 >& stSkillIDList)
{
    int iRet = 0;
    unsigned char ucNowStatID = stPlayerDetailInfo._stSoulData._ucNowStat;
    for (unsigned char i = 0; i <= ucNowStatID; ++i)
    {
        CSoulStatConfigData stStatConfigData;
        iRet = _stSoulStatConfig.GetConfig(i, stStatConfigData);
        if (iRet != 0)
        {
            CT_ERROR(("%d", i));
            return RET_SYS_ERROR;
        }

        stSkillIDList.Add(stStatConfigData.GetSkillIDByCareer(stPlayerBaseInfo._ucCareer));
    }

    return 0;
}

int CSoulMgr::GetBallTotal(CPlayerSoulData& stSoulData, unsigned char ucBallID, CPlayerAttr& stPlayerAttr)
{
    int iRet = 0;
    stPlayerAttr.Clear();
    CSoulBallConfigData stBallConfigData;
    iRet = _stSoulBallConfig.GetConfig(ucBallID, stBallConfigData);
    CHECK_RETURN(iRet);

    unsigned char ucBallLevel;
    iRet = stSoulData.GetBallLevel(ucBallID, ucBallLevel);
    CHECK_RETURN(iRet);
    
    return stBallConfigData.GetBallTotalAttr(ucBallLevel, stPlayerAttr);
}

int CSoulMgr::GetBallLevel(CPlayerSoulData& stSoulData, unsigned char ucBallID, CPlayerAttr& stPlayerAttr)
{
    int iRet = 0;
    stPlayerAttr.Clear();
    CSoulBallConfigData stBallConfigData;
    iRet = _stSoulBallConfig.GetConfig(ucBallID, stBallConfigData);
    CHECK_RETURN(iRet);

    unsigned char ucBallLevel;
    iRet = stSoulData.GetBallLevel(ucBallID, ucBallLevel);
    CHECK_RETURN(iRet);

    return stBallConfigData.GetBallLevelAttr(ucBallLevel, stPlayerAttr);
}

int CSoulMgr::GetSoulInfo(CPlayerSoulData& stSoulData, MsgSoulInfo& stSoulInfo)
{
    int iRet = 0;
    stSoulInfo.set_now_stat_id(stSoulData._ucNowStat);

    CSoulStatConfigData stStatConfigData;
    iRet = _stSoulStatConfig.GetConfig(stSoulData._ucNowStat, stStatConfigData);
    CHECK_RETURN(iRet);

    for (int i = 0; i < stStatConfigData._astBallIDs.Size(); ++i)
    {
        unsigned char ucBallID = stStatConfigData._astBallIDs[i];
        CSoulBallConfigData stBallConfigData;
        iRet = _stSoulBallConfig.GetConfig(ucBallID, stBallConfigData);
        CHECK_RETURN(iRet);

        MsgBallInfo* pstMsgBallInfo = stSoulInfo.add_balls();
        pstMsgBallInfo->set_ball_id(ucBallID);
        unsigned char ucBallLevel = 0;
        iRet = stSoulData.GetBallLevel(ucBallID, ucBallLevel);
        CHECK_RETURN(iRet);
        pstMsgBallInfo->set_ball_level(ucBallLevel);
        
        CPlayerAttr stAttr;
        stBallConfigData.GetBallTotalAttr(ucBallLevel, stAttr);

        CPlayerAttr::T_ATTR_DATAS stAttrData;
        stAttr.GetAttr(stAttrData);

        for (int j = 0; j < stAttrData.Size(); ++j)
        {
            MsgTypeValuePair *pstAttr = pstMsgBallInfo->add_attr();
            pstAttr->set_type(stAttrData[j]._ucType);
            pstAttr->set_value(stAttrData[j]._iValue);
        }
    }

    return 0;
}

int CSoulMgr::GetSoulAttr(CPlayerSoulData& stSoulData, CPlayerAttr& stAttr)
{
    int iRet = 0;
    stAttr.Clear();
    for (unsigned char i = 1; i < stSoulData._ucNowStat; ++i)
    {
        CPlayerAttr stStatAttr;
        iRet = _stSoulStatConfig.GetStatTotalAttr(i, stStatAttr);
        CHECK_RETURN(iRet);
        stAttr += stStatAttr;
    }

    CSoulStatConfigData stStatConfigData;
    iRet = _stSoulStatConfig.GetConfig(stSoulData._ucNowStat, stStatConfigData);
    CHECK_RETURN(iRet);

    for (int i = 0; i < stStatConfigData._astBallIDs.Size(); ++i)
    {
        unsigned char ucBallID = stStatConfigData._astBallIDs[i];

        unsigned char ucBallLevel;
        iRet = stSoulData.GetBallLevel(ucBallID, ucBallLevel);
        CHECK_RETURN(iRet);

        if (ucBallLevel == 0)
        {
            continue;
        }

        CSoulBallConfigData stBallConfigData;
        iRet = _stSoulBallConfig.GetConfig(ucBallID, stBallConfigData);
        CHECK_RETURN(iRet);

        CPlayerAttr stBallAttr;
        iRet = stBallConfigData.GetBallTotalAttr(ucBallLevel, stBallAttr);
        CHECK_RETURN(iRet);

        stAttr += stBallAttr;
    }

    return 0;
}

